# -*- coding: utf-8 -*-
import os
import time
import subprocess
import uiautomator2
import wx
import ui
import threading
###########################################################################
## my_Popen: 解决cmd中的句柄问题
###########################################################################
def my_Popen(cmd):
    proc = subprocess.Popen(cmd, shell=True,
                            stdout=subprocess.PIPE,
                            stdin=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    return proc.stdout.read().decode()

###########################################################################
## conn : 将设备与uiautomator连接的方法
###########################################################################
class ConnectDevice:
    def connect_device(self,device_id):
        try:
            self.device= uiautomator2.connect(device_id)
            return self.device
        except Exception as e:
            show_info(e)


conn = ConnectDevice()


###########################################################################
## Loading界面功能：显示等待动画
###########################################################################
class MyLoading(ui.Loading):
    def wait_txt(self):
        for t in range(8):
            list = ['请稍等.', '请稍等..', '请稍等...', '请稍等']
            for i in list:
                time.sleep(1)
                self.m_staticText1.SetLabel(i)
        self.Close()

    def wait_ui(self,event):
        t=threading.Thread(target=self.wait_txt)
        t.setDaemon(True)
        t.start()


def show_loading():
    app = wx.App(False)
    wait = MyLoading(None)
    wait.Centre()
    wait.Show()
    app.MainLoop()

###########################################################################
## Error界面功能：接收提示信息并显示到窗口
###########################################################################
class MyInfo(ui.Info):
    def get_info(self,e):
        self.e =e

    def set_info(self):
        self.m_staticText4.SetLabelText(str(self.e))

    def info_txt(self, event):
        th_info = threading.Thread(target=self.set_info)
        th_info.start()

def show_info(e):
    app = wx.App(False)
    info = MyInfo(None)
    info.get_info(e)
    info.Centre()
    info.Show()
    app.MainLoop()

###########################################################################
## Work界面功能：执行自动化功能
###########################################################################
class MyWork(ui.Work):
    def get_device(self, event):
        get_devices_cmd = 'adb devices'
        cmd_result = my_Popen(get_devices_cmd).splitlines()
        result = cmd_result[1:-1]
        self.devices_list = []
        if result:
            for i in result:
                ii = i.split()
                # ii.remove('device')
                self.device = ii[0]
                self.devices_list.append(self.device)  # devices 为当前adb devices获取到的所有设备SN，每个设备SN为一个元素，元素类型为str
            show_info(e="成功获取到设备{}".format(str(self.devices_list)))
        else:
            show_info(e="未获取到设备，请检查设备是否正常连接或开启Debug模式")

    def conn_autobjs(self, event):
        th1=threading.Thread(target=self.connect_method)
        th1.start()
        show_loading()
        th1.join()
        self.d.press("Home")

    def connect_method(self):
        self.d_dict = {}
        for i in  self.devices_list:
            self.d= conn.connect_device(i)
            #self.d_list = [].append(self.d)  #该方法无法获取到多个uiautomator对象
            d_dict = {i:self.d}
            self.d_dict.update(d_dict)

    def get_output(self,txt):
        try:
            self.txt = txt + "\n"
            self.m_textCtrl2.AppendText(self.txt)
        except Exception as e:
            show_info(e)
    # def output_txt(self, event):
    #     th_txt =threading.Thread(target=self.get_output,args=(self.txt,))
    #
    #     th_txt.start()

    def show_controls(self,event):
        control = self.m_choice2.GetCurrentSelection()
        if control == 3:  # 选择Reader操作即显示执行次数，选择前翻页和后翻页
            self.m_staticText9.Show()
            self.m_textCtrl3.Show()
            self.m_choice3.Show()
        elif control == 2:  # 选择笔记操作即显示执行次数
            self.m_staticText9.Show()
            self.m_textCtrl3.Show()
        elif control == 1 : # 选择书城操作即隐藏执行次数，翻页和路径
            self.m_staticText9.Hide()
            self.m_textCtrl3.Hide()
            self.m_choice3.Hide()
            self.m_staticText10.Hide()
            self.m_textCtrl4.Hide()
            self.m_staticText11.Hide()
            self.m_textCtrl5.Hide()
        elif control ==  0: # 选择书城操作即隐藏执行次数，翻页和路径
            self.m_staticText9.Hide()
            self.m_textCtrl3.Hide()
            self.m_choice3.Hide()
            self.m_staticText10.Hide()
            self.m_textCtrl4.Hide()
            self.m_staticText11.Hide()
            self.m_textCtrl5.Hide()
        elif control ==4: #选择Reader操作即显示执行次数，选择前翻页和后翻页
            self.m_staticText9.Show()
            self.m_textCtrl3.Show()
            self.m_choice3.Show()
        elif control ==5: #选择APK显示路径
            self.m_staticText10.Show()
            self.m_textCtrl4.Show()
            self.m_staticText11.Show()
            self.m_textCtrl5.Show()
            self.m_staticText9.Hide()
            self.m_textCtrl3.Hide()
            self.m_choice3.Hide()
        self.SendSizeEvent()

    def get_times(self):
        try:
            times = self.m_textCtrl3.GetValue()
            t = int(times)
            return t
        except Exception as e:
            show_info(e)

    def get_filepath(self):
        filepath = self.m_textCtrl4.GetValue()
        if filepath:
            return filepath
        else:
            show_info("存放APK文件的路径不能为空")
    def get_targetpath(self):
        targetpath= self.m_textCtrl5.GetValue()
        if targetpath:
            return targetpath
        else:
            return "/sdcard/Download"


    def work(self, event):
        index = self.m_choice2.GetCurrentSelection()
        if index == 0:  # 如果选择的是书城自动登录
            th = threading.Thread(target=self.store_login)
            th.start()

        elif index == 1:#如果选择的是书城自动点击
            th = threading.Thread(target=self.store_click)
            th.start()

        elif index == 2:  # 如果选择的是自动打开笔记增加笔画
            th_draw =threading.Thread(target=self.draw_package)
            th_draw.start()
            #self.draw_package()
        elif index == 3:  # 如果选择的是Reader自动翻页
            th_turnpage=threading.Thread(target=self.turn_page_package)
            th_turnpage.start()

        elif index == 4:  # 如果选择的是Reader自动翻页并增加笔画
            th_turn_draw=threading.Thread(target=self.draw_turnpage_package())
            th_turn_draw.start()

        elif index == 5:  # 如果选择的是APK安装
            th = threading.Thread(target=self.push_install_files)
            self.get_output("开始传输apk")
            th.start()

##############################自动化功能#####################################
##############################书城#####################################
    def store_login(self):
        try:
            for i in self.devices_list:
                obj = self.d_dict[i]
                obj.settings['operation_delay'] = (0,0.5) # 全局设置每次单击UI后再次单击之间延迟0.5s
                self.get_output("开始执行自动登录...")
                obj.press("home")
                obj(resourceId="元素定位")[1].click()
                # 书城点击头像
                obj(resourceId="元素定位").click()
                obj(text="立即登录").click()
                # 输入账号密码
                obj(resourceId="元素定位").set_text("reading")
                obj.sleep(1)
                obj(resourceId="元素定位").set_text("123456")
                obj(text="登录").click()
                obj.sleep(1)
                obj(resourceId="元素定位")[1].click()
                self.get_output("{}登录成功".format(i))
        except Exception as e:
            self.get_output(str(e))

    def store_click(self):
        try:
            for i in self.devices_list:
                obj = self.d_dict[i]
                obj.settings['operation_delay'] = (0,0.5)  # 全局设置每次单击UI后再次单击之间延迟0.5s
                self.get_output("开始执行自动点击操作...")
                obj.sleep(1)
                obj(text="分类").click()
                obj.sleep(1)
                obj(text="出版").click()
                obj(className="android.widget.LinearLayout", index="4").click()
                obj.sleep(3)
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                my_Popen("adb -s {} shell input keyevent 92".format(i))
                obj(className="android.widget.LinearLayout", index="3").click()
                obj.sleep(1)
                # 逐级返回
                obj(resourceId="元素定位").click()
                obj.sleep(3)
                obj(resourceId="元素定位").click()
                obj(text="男生").click()
                obj(className="android.widget.LinearLayout", index="4").click()
                obj.sleep(3)
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                my_Popen("adb -s {} shell input keyevent 92".format(i))
                obj(className="android.widget.LinearLayout", index="3").click()
                obj.sleep(1)
                obj(resourceId="元素定位").click()
                obj.sleep(3)
                obj(resourceId="元素定位").click()
                obj(text="女生").click()
                obj(className="android.widget.LinearLayout", index="4").click()
                obj.sleep(3)
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                my_Popen("adb -s {} shell input keyevent 92".format(i))
                obj(className="android.widget.LinearLayout", index="3").click()
                obj.sleep(1)
                obj(resourceId="元素定位").click()
                obj.sleep(3)
                obj(resourceId="元素定位").click()
                self.get_output("自动点击完成")
        except Exception as e:
            self.get_output(str(e))

##############################笔记#####################################
    def draw(self):
        try:
            for i in self.devices_list:
                obj = self.d_dict[i]
                obj.press("home")
                obj(resourceId="元素定位")[2].click()
                obj(resourceId="元素定位").click()
                obj.sleep(1)
                my_Popen("adb -s {} shell am broadcast -a test".format(i))
                self.get_output("{}绘制完成".format(i))
                obj.sleep(1)
                obj.press("home")
        except Exception as e:
            self.get_output(str(e))

    def draw_package(self):
        try:
            t = self.get_times()
            if t > 0:
                for i in range(t):
                    self.get_output("第{}次创建笔记".format(i+1))
                    self.draw()
            else:
                show_info("执行次数不少于1次")
        except Exception as e:
            show_info(e)
##############################Reader#####################################
    def turn_page_forward(self):
        try:
            for i in self.devices_list:
                my_Popen("adb -s {} shell input keyevent 92".format(i))
        except Exception as e:
            self.get_output(str(e))
    def turn_page_backward(self):
        try:
            for i in self.devices_list:
                my_Popen("adb -s {} shell input keyevent 93".format(i))
        except Exception as e:
            self.get_output(str(e))
    def turn_page_package(self):
        try:
            t = self.get_times()
            if 0 < t < 1000000:
                ori = self.m_choice3.GetCurrentSelection()
                if ori == 0:  # 默认向后翻页
                    for i in range(t):
                        self.get_output("第{}次翻页".format(i+1))
                        self.turn_page_backward()
                        time.sleep(0.5)
                else:  # 选择向前翻页
                    for i in range(t):
                        self.get_output("第{}次翻页".format(i+1))
                        self.turn_page_forward()
                        time.sleep(0.5)
                self.get_output("执行翻页完毕")
            else:
                show_info("执行次数范围：1~999999")
        except Exception as e:
            show_info(e)

    def draw_forward(self):
        try:
            for i in self.devices_list:
                my_Popen('adb -s {} shell am broadcast -a test --ei "args_shape_count" 50'.format(i))
                time.sleep(1)
                my_Popen("adb -s {} shell input keyevent 92".format(i))
                time.sleep(1)
        except Exception as e:
            self.get_output(str(e))
    def draw_backward(self):
        try:
            for i in self.devices_list:
                my_Popen('adb -s {} shell am broadcast -a test --ei "args_shape_count" 50'.format(i))
                time.sleep(1)
                my_Popen("adb -s {} shell input keyevent 93".format(i))
                time.sleep(1)
        except Exception as e:
            self.get_output(str(e))
    def draw_turnpage_package(self):
        try:
            t = self.get_times()
            if 0 < t < 1000000:
                ori = self.m_choice3.GetCurrentSelection()
                if ori == 0:  # 默认向后翻页
                    for i in range(t):
                        self.get_output("第{}次绘制并翻页".format(i+1))
                        self.draw_backward()
                        time.sleep(0.5)
                    self.get_output("已完成所有操作。")
                else:  # 选择向前翻页
                    for i in range(t):
                        self.get_output("第{}次绘制并翻页".format(i+1))
                        self.draw_forward()
                        time.sleep(0.5)
                    self.get_output("已完成所有操作。")
            else:
                show_info("执行次数范围：1~999999")
        except Exception as e:
            show_info(e)
##############################APK#####################################
    def push_install_files(self):
        try:
            filepath = self.get_filepath()
            targetpath = self.get_targetpath()
            files = os.listdir(filepath)  ## type:list 元素为文件名
            res_list=[]
            for i in self.devices_list:
                for file in files:
                    cmd = r'adb -s {} push {}\{} {}'.format(i,filepath,file,targetpath)
                    res=my_Popen(cmd)
                    res_list.append(res)
                    self.get_output("{}已完成{}传输！请等待安装...".format(i,file))
                if len(res_list) == len(files):  #检测是否完成推送 （打印push结果数量与文件数量一致则判断为推送完毕）
                    file_type = 'apk'    #判断文件是否为apk安装包
                    for file in files:   #遍历apk并安装
                        if file_type in file:
                            cmd = r'adb -s {} install {}\{}'.format(i, filepath, file)
                            my_Popen(cmd)
                        else:
                            pass
                    self.get_output("{}已完成所有apk安装！".format(i))
            self.get_output("全部设备已完成APK安装！")
        except Exception as e:
            show_info(e)


    # def auto_install_app(self):
    #
    #     try:
    #         filepath = self.get_filepath()
    #         files = os.listdir(filepath)
    #         file_type = 'apk'
    #         for i in self.devices_list:
    #             for file in files:
    #                 if file_type in file:
    #                     cmd =r'adb -s {} install {}\{}'.format(i,filepath,file)
    #                     my_Popen(cmd)
    #                 else:
    #                     pass
    #         self.get_output("已全部安装完成！")
    #     except Exception as e:
    #         show_info(e)
###########################################################################
## Work界面运行
###########################################################################
def show_work():
   try:
        app = wx.App(False)
        app.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED)
        work = MyWork(None)
        work.Centre()
        work.Show()
        app.MainLoop()
   except Exception as e:
       show_info(e)







